#include "stdafx.h"
#include "window.h"
#include "coresettings.h"
#include "iengine.h"
#include "../demo/tileengine.h"
#include "idleengine.h"
#include "glwidget.h"

#include <QtOpenGL/QGLWidget>
#include <QtGui/QVBoxLayout>
#include <QtCore/QTimer>
#include <QtGui/QMenuBar>

#include <set>

namespace Core {

static const char WINDOW_TITLE[] =
        "3-D Ландшафт и прочие штуки | InfernalAd | powered by Qt";

static const unsigned ANIMATE_INTERVAL = 10;

class WindowPrivate
{
public:
    IEngine *_engine;
    GLWidget *_glWidget;
    Demo::TileEngine *_tileEngine;
    IdleEngine _idleEngine;
    QTimer _timer;

    WindowPrivate();
    ~WindowPrivate();
};

WindowPrivate::WindowPrivate()
    :_glWidget(0)
    ,_tileEngine(0)
{
}

WindowPrivate::~WindowPrivate()
{
    if (_tileEngine != 0)
        delete _tileEngine;
    if (_glWidget != 0)
        delete _glWidget;
}

Window::Window()
    :d(new WindowPrivate())
{
    setWindowTitle(QString::fromUtf8(WINDOW_TITLE));
    d->_glWidget = new GLWidget(this);
    resetEngine(&d->_idleEngine);

    QVBoxLayout *mainLayout = new QVBoxLayout(this);
    mainLayout->setContentsMargins(0, 0, 0, 0);

    {
        QMenuBar *bar = new QMenuBar(this);
        QMenu *mapActions = bar->addMenu(tr("Map actions"));
        QAction *create = mapActions->addAction(tr("Create map"));
        QAction *load = mapActions->addAction(tr("Load existing map"));
        QAction *save = mapActions->addAction(tr("Save map"));
        QAction *chooseMapType = mapActions->addAction(tr("Choose map type"));
        connect(create, SIGNAL(triggered()), d->_glWidget, SLOT(createMap()));
        connect(load, SIGNAL(triggered()), d->_glWidget, SLOT(loadMap()));
        connect(save, SIGNAL(triggered()), d->_glWidget, SLOT(saveMap()));
        connect(chooseMapType, SIGNAL(triggered()), d->_glWidget, SLOT(chooseMapGenerationMethod()));
        mainLayout->addWidget(bar);
    }

    mainLayout->addWidget(d->_glWidget);
    setLayout(mainLayout);

    Core::CoreSettings *settings = Core::CoreSettings::instance();
    setFixedSize(settings->windowWidth(), settings->windowHeight());

    connect(d->_glWidget, SIGNAL(glInitialized()), this, SLOT(onGlInitialized()));
    connect(&d->_timer, SIGNAL(timeout()), d->_glWidget, SLOT(animate()));
}

Window::~Window()
{
    delete d;
}

void Window::resetEngine(IEngine *engine)
{
    d->_engine = engine;
    d->_glWidget->resetEngine(engine);
}

void Window::onGlInitialized()
{
    d->_tileEngine = new Demo::TileEngine();
    resetEngine(d->_tileEngine);
    d->_timer.start(ANIMATE_INTERVAL);
}

void Window::keyPressEvent(QKeyEvent *event)
{
    d->_glWidget->keyPressEvent(event);
}

void Window::keyReleaseEvent(QKeyEvent *event)
{
    d->_glWidget->keyReleaseEvent(event);
}

void Window::enterEvent(QEvent *)
{
    d->_timer.start(ANIMATE_INTERVAL);
}

void Window::leaveEvent(QEvent *)
{
    d->_timer.stop();
}

}
